import numpy as np
from matplotlib import pyplot as plt, gridspec
plt.rcParams['font.family'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] =False
from sklearn.kernel_ridge import KernelRidge
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from .path_tools import generate_img_path

def scale_and_truncate(grades, min_val=0, max_val=110, target_min=1, target_max=100):
    # 截断超出范围的值
    grades_clipped = np.clip(grades, min_val, max_val)
    # 缩放到目标范围
    grades_scaled = ((grades_clipped - min_val) / (max_val - min_val)) * (target_max - target_min) + target_min
    return grades_scaled

def train_model(X, y, test_size=0.2, random_state=None, alpha=1.0, kernel='polynomial', gamma=0.1):
    kr = KernelRidge(alpha=alpha, kernel=kernel, gamma=gamma)  # 创建核岭回归模型
    kr.fit(X, y)  # 使用整个数据集训练模型
    y_pred = kr.predict(X)
    y_pred_processed = scale_and_truncate(y_pred).astype(float)
    y_processed = scale_and_truncate(y).astype(float)
    mse = mean_squared_error(y_processed, y_pred_processed)
    print(f"Mean Squared Error (on training data): {mse}")

    # 创建图形
    fig = plt.figure(figsize=(10, 10))

    # 使用gridspec来定义子图布局
    gs = gridspec.GridSpec(3, 1, height_ratios=[1, 0.1, 1])

    # 实际值与预测值对比图
    ax1 = fig.add_subplot(gs[0, 0])
    ax1.scatter(y_processed, y_pred_processed, color='blue', label='预测值')
    ax1.plot([min(y_processed), max(y_processed)], [min(y_processed), max(y_processed)],
             color='red', label='理想值')
    plt.tick_params(axis='x', labelsize=18)
    plt.tick_params(axis='y', labelsize=18)
    ax1.set_xlabel('实际值 (Actual Values)', fontsize=18)
    ax1.set_ylabel('预测值 (Predicted Values)', fontsize=18)
    ax1.set_title('实际值与预测值对比 (Actual vs Predicted Values)', fontsize=18)
    ax1.legend()

    # 空白子图
    ax_blank = fig.add_subplot(gs[1, 0])
    ax_blank.axis('off')  # 关闭坐标轴

    # 残差分布图
    residuals = y_processed - y_pred_processed
    ax2 = fig.add_subplot(gs[2, 0])
    ax2.hist(residuals, bins=20, color='blue', edgecolor='black')
    plt.tick_params(axis='x', labelsize=18)
    plt.tick_params(axis='y', labelsize=18)
    ax2.set_title('残差分布 (Residuals Distribution)', fontsize=18)
    ax2.set_xlabel('残差 (Residuals)', fontsize=18)
    ax2.set_ylabel('频数 (Frequency)', fontsize=18)

    plt.tight_layout()
    # plt.show()
    img_path = generate_img_path()
    plt.savefig(img_path)

    return kr, img_path


def predict_new_data(model, new_data):
    new_predictions = model.predict(new_data)
    new_predictions_processed = scale_and_truncate(new_predictions)
    return new_predictions_processed

